<?php
///
namespace lxsphp;

/**
 * 文件加载器
 *
 * @version $Id: Load.php 192 2014-07-18 02:27:45Z linsir123 $
 * @package lxsphp
 */
class Load
{
	/**
	 * 系统类列表，采用<<按需加载>>
	 *
	 * @var array
	 * @static
	 */
	static $LIST = array(
		'BASE' => array(
			///
			'lxsphp\App' => 'App.php',
			'lxsphp\Instance' => 'Instance.php',

			///
			'lxsphp\Core\Handler' => 'Core/Handler.php',
			'lxsphp\Core\Config' => 'Core/Config.php',
			'lxsphp\Core\Log' => 'Core/Log.php',
			'lxsphp\Core\Hook' => 'Core/Hook.php',
			'lxsphp\Core\Debugger' => 'Core/Debugger.php',

			///
			'lxsphp\Core\Mvc\Request' => 'Core/Mvc/Request.php',
			'lxsphp\Core\Mvc\Dispatcher' => 'Core/Mvc/Dispatcher.php',
			'lxsphp\Core\Mvc\Controller' => 'Core/Mvc/Controller.php',
			'lxsphp\Core\Mvc\View' => 'Core/Mvc/View.php',

			///
			'lxsphp\Store\Redis\Redis' => 'Store/Redis/Redis.php',

			///
			'lxsphp\Store\Pdo\Pdo' => 'Store/Pdo/Pdo.php',
			'lxsphp\Store\Pdo\Command\Table' => 'Store/Pdo/Command/Table.php',
			'lxsphp\Store\Pdo\Command\Command' => 'Store/Pdo/Command/Command.php',
			'lxsphp\Store\Pdo\Command\Exception' => 'Store/Pdo/Command/Exception.php',
			'lxsphp\Store\Pdo\Command\Expression' => 'Store/Pdo/Command/Expression.php',
		),
		'OTHER' => array()
	);

	/**
	 * APP过程加载的文件数
	 *
	 * @var array
	 * @static
	 */
	static $LOADED = array(__FILE__);

	/**
	 * 配置类自动加载
	 *
	 * @param string $class 类名
	 *
	 * @static
	 */
	static function __auto($class)
	{
		///
		if (isset(self::$LIST['BASE'][$class]))
			self::file(self::$LIST['BASE'][$class]);

		///
		elseif (isset(self::$LIST['OTHER'][$class]))
			self::file(self::$LIST['OTHER'][$class], null);
	}

	/**
	 * 注册类以便在使用时可以自动加载
	 *
	 * @param string $class 类名
	 * @param string $file 类对应的文件物理地址
	 *
	 * @static
	 */
	static function addClass($class, $file)
	{
		///
		self::$LIST['OTHER'][$class] = $file;
	}

	/**
	 * 注册类以便在使用时可以自动加载,对某个目录内的所有文件进行注册操作
	 *
	 * @param string $dir 类对应的文件目录物理地址
	 * @param array $excludes 不需要进行注册的文件的排除列表
	 * @param int $excludeType 排除方式(0不处理, 1进行加载)
	 *
	 * @static
	 */
	static function addClassByDir($dir, $excludes = array(), $excludeType = 0)
	{
		///
		if (! file_exists($dir)
			|| ! is_dir($dir)
		)
			return;

		///
		$files = glob($dir . "*.php");
		foreach ($files as $file) {
			$fileName = basename($file, ".php");
			if (in_array($fileName, $excludes)) {
				if ($excludeType == 1)
					self::file($file, null);
			}

			///
			else {
				$tmp = str_replace(APP_DIR, '', $file);
				$class = str_replace('/', '\\', explode('.', $tmp)[0]);
				self::addClass($class, $file);
			}
		}
	}

	/**
	 * 加载文件
	 *
	 * @param string $fileName 文件名
	 * @param string $dir 文件所在的目录
	 * @param bool $throw 若文件不存在是否抛出异常
	 *
	 * @throws \Exception
	 * @return mixed 若文件不存在返回`false`;否则返回`require`信息
	 * @static
	 */
	static function file($fileName, $dir = CORE_DIR, $throw = true)
	{
		///
		$file = $dir . $fileName;
		if (in_array($file, self::$LOADED))
			return false;

		///
		self::$LOADED[] = $file;
		if (file_exists($file))
			return require($file);

		///
		if ($throw)
			throw new \Exception("[APP] 文件不存在({$file})");

		///
		return false;
	}
}

/**
 * 自动注册
 */
spl_autoload_register(['lxsphp\Load', '__auto']);
